#include <iostream>
#include <cstring>

using namespace std;

template<typename T>
const T& mymax(const T& a, const T& b)
{
    cout << "1." << __PRETTY_FUNCTION__ << endl;
    return (a < b) ? b : a;
}

template<typename T>
const T& mymax(T& a, T& b)
{
    cout << "2." << __PRETTY_FUNCTION__ << endl;
    return (a < b) ? b : a;
}

template<typename T>
const T mymax(T *a, T *b)
{
    cout << "4." << __PRETTY_FUNCTION__ << endl;
    return (*a < *b) ? *b : *a;
}

int& mymax(int& a, int& b)
{
    cout << "3." << __PRETTY_FUNCTION__ << endl;
    return (a < b) ? b : a;
}

char* mymax(char* a, char* b)
{
    cout << "5." << __PRETTY_FUNCTION__ << endl;
    return strcmp(a, b) < 0 ? b : a;
}

int main() {

    int a = 1;
    int b = 2;

    mymax(a, b);

    int *p1 = &a;
    int *p2 = &b;

    cout << mymax(p1, p2) << endl;

    char *str1 = "hello";
    char *str2 = "Hellod";
    cout << mymax(str1, str2) << endl;

    return 0;
}
